Server-to-Server Webhooks
This guide describes how to add and configure custom server-to-server webhook.
Server-to-server webhooks is a premium feature and available on Launch and Grow plans.
Apphud's webhook system for subscriptions allows you to catch the moment when a subscription event occurs. You can use this data to implement custom logic or analytics on your own server. You simply need to specify a URL for POST-request.
Webhooks are being sent as POST request to specified URL.

How to Add Webhook?

Step 1
2
3
4
5
6
7
✅ 8
At Apphud go to "Integrations" section and add Custom webhook:
Enter webhook name and specify webhook URL. Events will be sent to this URL using POST-request:
You may optionally specify Secret token that will be sent with the webhook request in the X-Apphud-Token HTTP header. Use this token to validate received payloads.
Choose which between Production and Sandbox events to be sent via webhook:
Enable events on which you would like to receive webhook:
Enable integration:
Save changes:
Apphud sends only one request per webhook without retries.

Webhook Structure

The POST body for all webhooks follows the same structure:
1
{
2
"app": {},
3
"event": {},
4
"user": {}
5
}
Copied!
Let's look through each component of this structure.

App

This dictionary contains information about the app.
Field
Type
Description
app.uid
String
Apphud app ID.
app.bundle_id
String
iOS Bundle ID.
app.package_name
String
Android Package Name.

Event

This dictionary contains information about events.
Field
Type
Description
Possible values
event.id
String
Apphud event ID.
event.created_at
Date
Date when this event was created by Apphud.
event.name
String
Event name.
e.g. "trial_started"
event.properties
Dictionary
A dictionary containing event properties. View the description below.
event.receipt
Dictionary
Apphud receipt information related to the event. View the description below.

event.properties

event.properties may contain fields below.
Field
Type
Description
Possible values
event.properties.product_id
String
Product ID.
event.properties.reason
String
Depending on the event: the reason of an expiration of a subscription or the reason of refund.
user_canceled billing_issue declined_price_increase
unavailable_product
unknown_error
app_issue
another_reason
event.properties.currency
String
Local currency ISO code.
event.properties.usd_price
Float
Price in USD.
event.properties.local_price
Float
Price in local currency.
event.properties.offer_type
String
Introductory or promotional offer payment mode (iOS only).
pay_up_front
pay_as_you_go
trial
event.properties.offer_id
String
Promotional offer ID.
event.properties.unit
String
The increment of time that a subscription period is specified (iOS only).
day
week
month
year
event.properties.units_count
Integer
The number of units per subscription period (iOS only).

event.receipt

event.receipt may contain the fields below.
This is an internal Apphud receipt model.
Field
Type
Description
event.receipt.id
String
Apphud receipt ID.
event.receipt.product_id
String
Product ID.
event.receipt.purchased_at
Date
Transaction date.
event.receipt.intro_period
Boolean
Is subscription in an introductory period.
event.receipt.trial_period
Boolean
Is subscription in the trial period.
event.receipt.transaction_id
String
App Store transaction ID / Google Play Order ID
event.receipt.original_transaction_id
String
App Store original transaction ID / Google Play Purchase Token.
event.receipt.price_usd
Float
Price in USD.
event.receipt.proceeds_usd
Float
Revenue in USD after Apple / Google commission deduction.
event.receipt.price
Float
Price in local currency.
event.receipt.proceeds
Float
Revenue in local currency after Apple / Google commission deduction.
event.receipt.currency
String
Local currency ISO code.
event.receipt.quantity
Integer
Always 1.
event.receipt.apple_share
Float
Apple commission. It can be 0.15 or 0.3.

User

This dictionary contains information about the user.
Field
Type
Description
user.user_id
String
User ID.
user.uid
String
Apphud user ID.
user.paying
Boolean
Is the user currently paying or not.
user.payments_count
Integer
User payments count.
user.total_spent
Float
User total spent in USD.
user.idfv
String
User IDFV.
user.subscriptions[]
Array
An array containing information about all subscriptions of the user. View the description below.

user.subscriptions[]

user.subscriptions is an array containing user's subscriptions. Each element of this array is a dictionary with the following structure:
Field
Type
Description
Possible values
user.subscriptions[].id
String
Apphud subscription ID
user.subscriptions[].product_id
String
Product ID
user.subscriptions[].group
String
Group name
user.subscriptions[].status
String
Current status
trial
intro
promo
regular
refunded
expired
user.subscriptions[].intro_period
Boolean
Is subscription in an introductory period.
user.subscriptions[].trial_period
Boolean
Is subscription in the trial period.
user.subscriptions[].started_at
Date
Subscription start date.
user.subscriptions[].expires_at
Date
Subscription expiration date.
user.subscriptions[].cancelled_at
Date
Subscription cancellation date.
user.subscriptions[].autorenew_enabled
Boolean
Is auto-renew enabled for the subscription.
user.subscriptions[].in_retry_billing
Boolean
Is subscription in retry billing period.
user.subscriptions[].introductory_activated
Boolean
Is intro (including trial) was user by the user.
user.subscriptions[].environment
String
Subscription environment
sandbox
production
user.subscriptions[].original_transaction_id
String
App Store original transaction ID / Google Play Purchase Token

Webhooks Examples

Subscription Renewed
Subscription Expired
1
{
2
"app": {
3
"uid": "e0ce9fc3",
4
"bundle_id": "com.apphud.testapp",
5
"package_name" : "com.apphud.testapp"
6
},
7
"event": {
8
"id": "2c2cba55-c41e-4ef8-81a7-7c11b3715502",
9
"receipt": {
10
"id": "13f4134c-c123-42d8-aadb-b3c97bb72e3d",
11
"intro_period": false,
12
"price_usd": 4.35,
13
"purchased_at": "2020-01-21 11:51:33 UTC",
14
"transaction_id": "1000000617611104",
15
"original_transaction_id": "1000000615808360",
16
"trial_period": false,
17
"price": 269,
18
"quantity": 1,
19
"apple_share": 0.3,
20
"proceeds_usd": 3.0449999999999995,
21
"proceeds": 188.29999999999998,
22
"product_id": "BronzeMonthly",
23
"currency": "RUB"
24
},
25
"created_at": "2020-01-21 11:51:33 UTC",
26
"properties": {
27
"usd_price": 4.35,
28
"local_price": 269,
29
"product_id": "BronzeMonthly",
30
"currency": "RUB"
31
},
32
"name": "subscription_renewed"
33
},
34
"user": {
35
"user_id": "user_10",
36
"total_spent": 0,
37
"payments_count": 0,
38
"uid": "ce4aac3d",
39
"paying": false,
40
"subscriptions": [
41
{
42
"id": "e89c975d-aa18-4661-8a25-8e4a67c038de",
43
"status": "regular",
44
"environment": "sandbox",
45
"original_transaction_id": "1000000615808360",
46
"expires_at": "2020-01-21 11:41:17 UTC",
47
"cancelled_at": null,
48
"started_at": "2020-01-16 11:58:39 UTC",
49
"autorenew_enabled": false,
50
"in_retry_billing": false,
51
"introductory_activated": true,
52
"group": "Bronze",
53
"product_id": "BronzeMonthly",
54
"intro_period": false,
55
"trial_period": false
56
},
57
{
58
"id": "da27352b-2e25-48c1-8812-e8001e691d1f",
59
"status": "expired",
60
"environment": "sandbox",
61
"original_transaction_id": "1000000616814874",
62
"expires_at": "2020-01-19 15:55:19 UTC",
63
"cancelled_at": null,
64
"started_at": "2020-01-19 14:55:20 UTC",
65
"autorenew_enabled": false,
66
"in_retry_billing": false,
67
"introductory_activated": false,
68
"group": "Gold",
69
"product_id": "Gold2Months",
70
"intro_period": false,
71
"trial_period": false
72
}
73
]
74
}
75
}
Copied!
1
{
2
"app": {
3
"uid": "e0ce9fc3",
4
"bundle_id": "com.apphud.testapp"
5
},
6
"event": {
7
"id": "8e8544c6-bd5c-4f6a-a039-cc7639b65ae5",
8
"created_at": "2020-01-21 11:56:31 UTC",
9
"properties": {
10
"product_id": "BronzeMonthly",
11
"reason": "user_canceled"
12
},
13
"name": "subscription_expired"
14
},
15
"user": {
16
"user_id": "user_10",
17
"total_spent": 0,
18
"payments_count": 0,
19
"uid": "ce4aac3d",
20
"paying": false,
21
"subscriptions": [
22
{
23
"id": "e89c975d-aa18-4661-8a25-8e4a67c038de",
24
"status": "expired",
25
"environment": "sandbox",
26
"original_transaction_id": "1000000615808360",
27
"expires_at": "2020-01-21 11:56:33 UTC",
28
"cancelled_at": null,
29
"started_at": "2020-01-16 11:58:39 UTC",
30
"autorenew_enabled": false,
31
"in_retry_billing": false,
32
"introductory_activated": true,
33
"group": "Bronze",
34
"product_id": "BronzeMonthly",
35
"intro_period": false,
36
"trial_period": false
37
},
38
{
39
"id": "da27352b-2e25-48c1-8812-e8001e691d1f",
40
"status": "expired",
41
"environment": "sandbox",
42
"original_transaction_id": "1000000616814874",
43
"expires_at": "2020-01-19 15:55:19 UTC",
44
"cancelled_at": null,
45
"started_at": "2020-01-19 14:55:20 UTC",
46
"autorenew_enabled": false,
47
"in_retry_billing": false,
48
"introductory_activated": false,
49
"group": "Gold",
50
"product_id": "Gold2Months",
51
"intro_period": false,
52
"trial_period": false
53
}
54
]
55
}
56
}
Copied!

How to Test Webhook

You can test webhooks using any service that may receive HTTP events, for example, RequestBin.com.
Step 1
2
3
✅ 4
Open RequestBin.com and click the "Create Request Bin" button.
Copy Endpoint URL:
Create new Webhook in Apphud using this URL. Make sure you selected "Sandbox" environment while configuring webhook.
Make a test purchase on your device using Sandbox environment. You can read how to do this here. Now whenever webhook is triggered, you will see a full report on RequestBin:
Last modified 1mo ago