Connection Builder

You can build your own integration from scratch using various liquid macros.

Overview

The Custom Connection Builder lets you send custom POST requests to third-party services whenever selected in-app events occur. With it, you can recreate Apphud’s built-in integrations or design your own payloads for any supported event.

📘

Note

Connection Builder is available on Expert and Enterprise plans.


How to Add a Custom Connection

Step 1 – Create a Connection

In Apphud, navigate to Connections > Integrations, find Connection Builder at the top of the list, and click Add Connection.

As with other integrations, each custom connection is created for a specific data source platform. During setup, you’ll be prompted to select a Source:
iOS, Android, Flows, iOS (Web-to-App), or Android (Web-to-App).

Step 2 – Configure Name and URL

After selecting a source, you’ll be taken to the connection settings page. Enter a Name and URL for the connection. Events will be sent to the specified URL via POST requests.


Step 3 – Add Headers

Define request headers by specifying Header Name and Value.
To include multiple headers, click Add Header and fill in the additional fields.


Step 4 – Set Up Request Body

In the Body Configuration section, compose your JSON payload using supported Liquid macros (see macro reference below).

Step 5 – Select Events

Choose the events you'd like to send through the connection. You can also rename these events using custom labels.


Step 6 – Apply Event Filters (Optional)

Click + Where to add filters that determine when events should be sent.
If an event is enabled but doesn't match the filter conditions, it will appear as Skipped in the event logs with the reason “Event did not match filters.”

📘

Important Note

No need to create a filter "Environment = Production". By default Apphud skips sandbox events so this filter is redundant.

Add powerful event filters to ensure only specific data is sent to a destination. For example:

  • Revenue > $29
  • Product duration = Weekly
  • Trial started = true

These filters can be applied per connection for precise control.

Below is a list of available filters grouped by category:

General

Environment: Sandbox, Production
App Version: supports =, >, < (e.g., > 1.20.1)

User

Country by IP
Store Country Has Advertising ID (IDFA)

Product

Type: Auto-renewable, Non-renewing
Duration: Weekly, Monthly, Annually Family Shared Product ID Revenue (USD): supports comparison (<, >, =)

Attribution

Ad Network
Channel Campaign Name

User Properties

Keys with exact values

❗️

Note

Filters do not apply to non-receipt events like user_created, paywall_shown, except for Store Country and Environment.

Step 7

Save the Connection.
The connection can be Enabled right away, however, we recommend testing a connection before enabling it.

Liquid Macros List

App

MacroDescriptionFormatExample
{{ app.app_version }}App VersionString1.2.20
{{ app.bundle_id }}iOS Bundle IDStringcom.bundle.id
{{ app.package_name }}Android Package NameStringcom.android.package

Event

MacroDescriptionFormatExample
{{ event.created_at }}Event creation date (ISO)Date2022-03-12T09:38:38.081Z
{{ event.created_at_ts }}Event creation date (Unix seconds)Integer1743481200
{{ event.name }}Event nameStringcustom_trial_started
{{ event.original_name }}Unmodified original nameStringtrial_started
{{ event.receipt.product_id }}Product IDStringmy.weekly.id
{{ event.receipt.purchased_at }}Transaction date (ISO)Date2022-03-12T09:38:38.081Z
{{ event.receipt.purchased_at_ts }}Transaction date (Unix seconds)Integer1743481200
{{ event.receipt.intro_period }}Introductory period (true/false)BooleanTRUE
{{ event.receipt.trial_period }}Trial period (true/false)BooleanFALSE
{{ event.receipt.transaction_id }}Transaction IDString1000000999999999
{{ event.receipt.original_transaction_id }}Original Transaction IDString1000000888888888
{{ event.receipt.price_usd }}Price in USDFloat9.99
{{ event.receipt.proceeds_usd }}Proceeds in USDFloat6.99
{{ event.receipt.price }}Price in local currencyFloat199.00
{{ event.receipt.proceeds }}Proceeds in local currencyFloat139.00
{{ event.receipt.currency }}Local currency ISO codeStringUSD

User

MacroDescriptionFormatExample
{{ user.user_id }}User IDStringabc123xyz
{{ user.paying }}Is currently paying or notBooleanTRUE
{{ user.payments_count }}Payments countInteger4
{{ user.total_spent }}Total spent in USDFloat23.49
{{ user.idfv }}Device IDFVString12345-12345-12345
{{ user.idfa }}Device IDFAStringABCDEF12-3456-7890-ABCD-EF1234567890
{{ user.properties.your_key }}User PropertiesStringmyuserpropertyvalue
{{ user.created_at }}User Created Date (ISO)Date2022-03-12T09:38:38.081Z
{{ user.created_at_ts }}User Created Date (Unix seconds)Integer1743481200
{{ user.first_seen_at }}First seen Date (ISO)Date2022-03-12T09:38:38.081Z
{{ user.first_seen_at_ts }}First seen Date (Unix seconds)Integer1743481200
{{ user.country_by_ip }}Country ISO code by IP addressStringUS
{{ user.country_by_store }}Country ISO code from the storeStringUS
{{ user.time_zone }}Time zoneStringAsia/Jakarta
{{ user.language }}LanguageStringen
{{ user.ip_address }}IP addressString192.168.1.1
{{ user.os_version }}OS versionString18.2.1
{{ user.push_token }}Push tokenStringABCD1234TOKEN5678

User LTV Predictions (Coming Soon)

MacroDescriptionFormatExample
{{ user.pltv_30d }}30-day Predicted LTVFloat34.00
{{ user.pltv_90d }}90-day Predicted LTVFloat40.54
{{ user.pltv_365d }}365-day Predicted LTVFloat42.55

Attribution

MacroDescriptionFormatExample
{{ user.attribution.appsflyer_id }}AppsFlyer IDStringAF_ID_123456
{{ user.attribution.fb_anon_id }}Facebook Anon IDStringFBANONID123
{{ user.attribution.fb_ext_info }}Facebook Ext InfoStringEXTINFO_SAMPLE
{{ user.attribution.firebase_id }}Firebase IDStringfirebase-user-id
{{ user.attribution.adjust_id }}Adjust IDStringadjust-uuid-xyz
{{ user.attribution.provider }}Attribution providerStringApple Search Ads Integration
{{ user.attribution.ad_network }}Ad NetworkStringMeta Ads
{{ user.attribution.channel }}ChannelStringInstagram
{{ user.attribution.campaign }}CampaignStringmy-us-campaign
{{ user.attribution.fbc }}FBCStringfb.1.1234567890.111
{{ user.attribution.fbp }}FBPStringfb.1.1234567890.222

Click Event

MacroDescriptionFormatExample
{{ user.attribution.ttclid }}TikTok Click IDStringtiktok-click-id-xyz
{{ user.attribution.gclid }}Google Click IDStringGOOGLE123CLICK
{{ user.click_event.properties.custom_param }}Click event custom paramStringvalue

MacroDescriptionFormatExample
{{ user.click_event.properties.click_id }}Click IDStringclick1234
{{ user.click_event.user_agent }}User Agent from click eventStringMozilla...
{{ user.click_event.properties.utm_campaign }}UTM CampaignStringspring_sale
{{ user.flow_properties.any_custom_param }}Flow custom paramStringvalue2

Special Functions

You can also check the "Remove null values" setting under the "Request body" field to ensure such parameters won't be sent.

Conditional Logic in JSON

With Connection Builder, you can embed conditional logic directly in your request body using Liquid if/else tags.

Example: Send a has_idfa flag based on the availability of IDFA:

"has_idfa": {% if user.idfa %} 1 {% else %} 0 {% endif %}

You can also apply conditions to multi-line blocks or entire JSON payloads:

{% if user.country == "US" %}
{ "region": "NA" }
{% else %}
{ "region": "Other" }
{% endif %}

Value Modifiers

Transform values on the fly using built-in modifiers. Examples include arithmetic operations, string formatting, and date formatting.

Arithmetic:

"revenue_x2": {{ event.receipt.price | times: 2 }}

String case formatting:

"product": "{{ event.receipt.product_id | upcase }}"

Date formatting:
For more on date formatting, check this Liquid guide.

"event_time": "{{ event.created_at | date: "%Y-%m-%d %H:%M:%S.000" }}"

UNIX timestamp:

"timestamp": "{{ event.created_at | date: "%s" }}"

For more on date formatting, check this Liquid guide.

Preview a Payload

While setting up your integration, you can preview the generated payload at any time. Click the eye 👁️ icon in the JSON editor toolbar, then enter an Event ID or Transaction ID to view the payload.

  • Event ID. It's the Apphud's internal event ID which can be found in the Events tab. Include ID column in the table. If the ID column doesn't exist, try to clear browser cache first.
  • Transaction ID. Store's Transaction ID.

Note: This preview does not trigger an actual HTTP request.

Test a Connection

To simulate a real connection, enter a valid Transaction ID from your app. Apphud will fetch the corresponding event, receipt, and user data, then send a test POST request using your configuration.

All configured filters will be applied during the test.

Note: If you're using a sandbox transaction, be sure to include the filter Environment = Sandbox. Otherwise, the event will be skipped.

  • If the transaction is invalid or belongs to a different app, an error message will appear: "Transaction was not found."
  • If the test is successful, a popup will display the response payload.
    ⚠️ Keep in mind: the test result is shown only once and cannot be accessed again after closing the popup.